package handler

import (
	"fmt"
	"net/http"

	"github.com/gccai/write_helper/enum"
	"github.com/gccai/write_helper/model"
	"github.com/gccai/write_helper/query"
	"github.com/gccai/write_helper/resp"
	"github.com/gccai/write_helper/service"
	"github.com/gin-gonic/gin"
)

type BookHandler struct {
	BookSrv service.BookSrvInterface
}

// 无非就是增删改查
type BookHandlerInterface interface {
	GetEntity(res model.Book) resp.Book
	BookInfoHandler(c *gin.Context) //需要俩个实体类，1是book，2是chapter
	BookListHandler(c *gin.Context)
	AddBookHandler(c *gin.Context)
	EditBookHandler(c *gin.Context)
	DeleteBookHandler(c *gin.Context)
}

func (b *BookHandler) GetEntity(res model.Book) resp.Book {
	return resp.Book{
		BookName:          res.BookName,
		WriterName:        res.WriterName,
		UserId:            res.UserId,
		StoryCore:         res.StoryCore,
		BriefIntroduction: res.BriefIntroduction,
		UpdateAt:          res.UpdateAt,
	}
}

// http://localhost:8888/api/book/info/:bookName
func (b *BookHandler) BookInfoHandler(c *gin.Context) {
	entity := resp.Entity{
		Code: int(enum.OperateFail),
		Msg:  enum.OperateFail.String(),
		Data: nil,
	}
	userId := c.Param("userId")
	bookName := c.Param("bookName")
	var book model.Book
	book.BookName = bookName
	book.UserId = userId
	res, err := b.BookSrv.GetOneBook(&book)
	if err != nil {
		entity.Msg = err.Error()
		c.JSON(http.StatusInternalServerError, gin.H{"entity": entity})
		return
	}
	entity.Code = int(enum.OperateOk)
	entity.Msg = enum.OperateOk.String()
	entity.Data = *res
	c.JSON(http.StatusOK, gin.H{"entity": entity})
}

// http://localhost:8888/api/book/list?page=0&&pageSize=1&&writerName=abc
func (b *BookHandler) BookListHandler(c *gin.Context) {
	entity := resp.Entity{
		Code:      int(enum.OperateFail),
		Msg:       enum.OperateFail.String(),
		Data:      nil,
		Total:     0,
		TotalPage: 1,
	}

	var q query.BookListQuery
	err := c.ShouldBindQuery(&q)
	if err != nil {
		entity.Msg = err.Error()
		c.JSON(http.StatusInternalServerError, gin.H{"entity": entity})
		return
	}
	// fmt.Println(q)
	req := query.ListQuery{
		Page:     q.Page,
		PageSize: q.PageSize,
	}
	books, err := b.BookSrv.BookList(&req, q.UserId)
	if err != nil {
		entity.Msg = err.Error()
		c.JSON(http.StatusInternalServerError, gin.H{"entity": entity})
		return
	}
	var newList []resp.Book
	for _, book := range books {
		newList = append(newList, b.GetEntity(*book))
	}

	total, err := b.BookSrv.GetTotal(q.UserId)
	if err != nil {
		entity.Msg = err.Error()
	}
	var pageSize int = 0
	var page int = 0
	if q.PageSize > 10 {
		pageSize = q.PageSize
	} else {
		pageSize = 10
	}
	ret := int(total / pageSize)
	ret2 := total % pageSize
	if ret2 == 0 {
		page = ret
	} else {
		page = ret + 1
	}
	response := resp.Entity{
		Code:      http.StatusOK,
		Msg:       "OK",
		TotalPage: page,
		Total:     total,
		Data:      newList,
	}
	c.JSON(http.StatusOK, gin.H{"entity": response})

}

// http://localhost:8888/api/book/add
func (b *BookHandler) AddBookHandler(c *gin.Context) {
	entity := resp.Entity{
		Code: int(enum.OperateFail),
		Msg:  enum.OperateFail.String(),
		Data: nil,
	}

	var book model.Book
	err := c.ShouldBindJSON(&book)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"entity": entity})
		return
	}
	if book.UserId == "" {
		c.JSON(http.StatusInternalServerError, gin.H{"entity": entity})
		return
	}
	_, err = b.BookSrv.Add(&book)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"entity": entity})
		return
	}
	entity.Code = http.StatusOK
	entity.Msg = "OK"
	c.JSON(http.StatusOK, gin.H{
		"entity": entity,
	})

}

//http://localhost:8888/api/book/edit
// TODO 只有当userid和书籍名字都正确的时候才能更改成功，但是只有userid正确的时候，也报成功，但是实际上却修改失败。
func (b *BookHandler) EditBookHandler(c *gin.Context) {
	entity := resp.Entity{
		Code: int(enum.OperateFail),
		Msg:  enum.OperateFail.String(),
		Data: nil,
	}
	book := model.Book{}
	err := c.ShouldBindJSON(&book)
	// fmt.Println(err.Error())
	if err != nil {
		fmt.Println("this")
		c.JSON(http.StatusInternalServerError, gin.H{"entity": entity})
		return
	}
	// fmt.Println(book)
	res, err := b.BookSrv.Edit(&book)
	if !res {
		entity.Msg = err.Error()
		c.JSON(http.StatusInternalServerError, gin.H{"entity": entity})
		return
	}
	entity.Code = http.StatusOK
	entity.Msg = "OK"
	c.JSON(http.StatusOK, gin.H{
		"entity": entity,
	})

}

// http:localhost:8888/api/book/delete/:userId/:bookName
func (b *BookHandler) DeleteBookHandler(c *gin.Context) {
	entity := resp.Entity{
		Code: int(enum.OperateFail),
		Msg:  enum.OperateFail.String(),
		Data: nil,
	}
	userId := c.Param("userId")
	bookName := c.Param("bookName")
	if userId == "" || bookName == "" {
		c.JSON(http.StatusInternalServerError, gin.H{
			"entity": entity,
		})
		return
	}
	var book model.Book
	book.UserId = userId
	book.BookName = bookName
	fmt.Println(book)
	res, err := b.BookSrv.Delete(&book)
	if !res {
		entity.Msg = err.Error()
		c.JSON(http.StatusInternalServerError, gin.H{
			"entity": entity,
		})
		return
	}
	entity.Code = http.StatusOK
	entity.Msg = "OK"
	c.JSON(http.StatusOK, gin.H{"entity": entity})
}
